C.S.M.P. Digest Sat, 13 Mar 93 Volume 2 : Issue 19 Today's Topics: Scope of trap patches HELP! What IS this bug appleevents Help with strings.... Getting a dirID from an FSSpec. HELP! The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly. The digest is a collection of article threads from the usenet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you can post articles to any newsgroup by mailing your article to newsgroup@cs.utexas.edu So, to post an article to comp.sys.mac.programmer, mail your article to comp-sys-mac-programmer@cs.utexas.edu Note the '-' instead of '.' in the newsgroup name. Be sure to ask that replies be emailed to you instead of posted to the group, and give your email address. Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at cs.uoregon.edu). Article threads are not added to the digest until the last article added to the thread is at least one month old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the file /pub/mac/csmp-digest/README before downloading any files. The most recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex archive has a mail server; send a message with the text '$MACarch help' (no quotes) to LISTSERV@ricevm1.rice.edu for more information. The digest is also available via email. Just send a note saying that you want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will automatically receive each new issue as it is created. Sorry, back issues are not available through the mailing list. Send administrative mail to mkelly@cs.uoregon.edu. ------------------------------------------------------- From: lardieri@ernie.Princeton.EDU (Stephen Peter Lardieri) Subject: Scope of trap patches Organization: Princeton University Date: Sun, 7 Feb 1993 03:26:31 GMT It would appear, under System 7.1, that an application calling SetTrapAddress or NSetTrapAddress only patches a trap with respect to itself -- other applications, launched either before or after the one doing the patching, still get the original, unpatched trap. Is it possible to patch a trap in a global fashion from an application, so that all other apps will use the patched trap? Or is the only way to do this with INIT code? +++++++++++++++++++++++++++ From: cole@alexia.lis.uiuc.edu (Sandra Stewart-Cole) Date: Sun, 7 Feb 1993 06:40:00 GMT Organization: University of Illinois at Urbana In <1993Feb7.032631.12987@Princeton.EDU> lardieri@ernie.Princeton.EDU (Stephen Peter Lardieri) writes: >It would appear, under System 7.1, that an application calling >SetTrapAddress or NSetTrapAddress only patches a trap with respect >to itself -- other applications, launched either before or after >the one doing the patching, still get the original, unpatched >trap. Not just 7.1. Anything post-MultiFinder. In fact, Switcher (the ancestor of sorts to MultiFinder) swapped out trap patches. >Is it possible to patch a trap in a global fashion from an application, >so that all other apps will use the patched trap? Or is the only >way to do this with INIT code? Maybe there's a way, but from what I've seen of how the spawning of applications works, you would need to hunt down every app's trap table off in the undocumented (because you aren't supposed to fiddle or rely on it's structure) memory zone that wraps around all the various applications. Apple is NOT likely to tell anyone how to mess around out there, but if you have a bit of time and MacsBug you could snoop for the necessary info to do it. (IOW: The only way is INIT code.) Bill Stewart-Cole +++++++++++++++++++++++++++ Date: 7 Feb 93 23:12:26 GMT Organization: Royal Institute of Technology, Stockholm, Sweden In <1993Feb7.032631.12987@Princeton.EDU> lardieri@ernie.Princeton.EDU (Stephen Peter Lardieri) writes: >Is it possible to patch a trap in a global fashion from an application, >so that all other apps will use the patched trap? Or is the only >way to do this with INIT code? You answered your question yourself... Cheers, / h+ - -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe -- This signature is kept shorter than 4 lines in the interests of UseNet S/N ratio. +++++++++++++++++++++++++++ From: rmah@panix.com (Robert Mah) Organization: PANIX Public Access Unix, NYC Date: Mon, 8 Feb 1993 07:06:11 GMT tte) writes: >In <1993Feb7.032631.12987@Princeton.EDU> lardieri@ernie.Princeton.EDU (Stephen Peter Lardieri) writes: >>Is it possible to patch a trap in a global fashion from an application, >>so that all other apps will use the patched trap? Or is the only >>way to do this with INIT code? I think (I am NOT sure) that if you set the new trap address to a location in the system heap then the patch will occur for all apps. You would have to move the code into the system heap yourself. Now, again, I'm not sure. Can anyone confirm or deny this possibly unfounded rumor? Cool Runnin' Rob - -- [----------------------------------------------------------------------] [ Robert S. Mah | Voice: 212-947-6507 | "Every day an adventure, ] [ One Step Beyond | EMail: rmah@panix.com | every moment a challenge" ] [----------------------------------------------------------------------] +++++++++++++++++++++++++++ From: lsr@taligent.com (Larry Rosenstein) Date: 8 Feb 93 22:07:45 GMT Organization: Taligent, Inc. In article , rmah@panix.com (Robert Mah) wrote: > > I think (I am NOT sure) that if you set the new trap address to a location > in the system heap then the patch will occur for all apps. You would That's not true under MultiFinder or System 7. There's no clean way for an application to make a global trap patch. It's not clear what that would mean if it was possible; would it apply to apps that are currently running? Also, I don't think it is recommended for applications to allocate memory in the system heap when patching traps. This used to be necessary for the 64K ROM tap dispatcher, but that was fixed a long time ago. Larry Rosenstein Taligent, Inc. lsr@taligent.com --------------------------- From: cole@alexia.lis.uiuc.edu (Sandra Stewart-Cole) Subject: HELP! What IS this bug Organization: University of Illinois at Urbana Date: Thu, 4 Feb 1993 05:53:43 GMT The bug I *THOUGHT* was a side effect of shoving a resource map into a commonly accessible spot turns out not to be that... The situation is that I have an INIT which patches SystemTask in order to get some regular time, and it talks to an external device via the serial port to determine whether to allow the user to do anything. In shutting off the user, it does a little screen blanking act and set SysEvtMask so that the mouse and keys are ignored. The program can for various reasons have to dialog with the user, using dialogs in a file I now only open as needed (and to hell with the user who moves it out from under me) The bug is that when I try to open a desk accessory, especially one which opens a dialog as it's priomary interface (Chooser and Quill for example) I get crashes in the data area of CDEF and WDEF'strying to open a DA before that file has ever even been touched, and I am seeing the SAME errors. Sadly, reproducibility is bad, with errors coming in different def functions every time I change a line of code (say top put a Debugger() call in, or an extra null pointer check) and coming in different ones for the 2 most consistent problem DA's (Chooser and Quill, both of which use a dialog box as main interface, and both of which are crashing inside the GetNewDialog call they use to get the dialog) I have determined that the suspect of the day is something I'm doing evil in QuickDraw. I use no QD but for a call to NewRgn in the INIT code, and in the SystemTask patch I presumeably will always have an app's A5 to base my new GrafPort on ( I use a raw GrafPort to blank the screen and draw a snide little migrating message to the user) and I only have my GrafPort aroubnd when the screen is blanked, so I THOUGHT I wouldn't have to fake out an InitGraf call, and in fact that it would be daBug work is a bit tedious since by the time I have a crash I am pretty far down the stack from the actual DA, and have passed thru a LOT of code and have a rather short A6 chaindue to some upstream ROM patches presumeably done by Apple (this is system 7 on a Plus, so I am chock full of patches that never LINK A6 to give me a clear path) +++++++++++++++++++++++++++ From: ray@netcom.com (Ray Fischer) Date: 7 Feb 93 21:41:41 GMT Organization: Netcom. San Jose, California cole@alexia.lis.uiuc.edu (Sandra Stewart-Cole) writes ... >The bug I *THOUGHT* was a side effect of shoving a resource map into a commonly >accessible spot turns out not to be that... The situation is that I have an >INIT which patches SystemTask in order to get some regular time, and it talks >to an external device via the serial port to determine whether to allow the >user to do anything. I don't know what you're trying to do, but in my opinion you're not suffering nearly enough for some of the truly strange things you're doing. No, it's probably not reasonable to assume A5 will be valid everytime you intercept SystemTask. Were I writing this sort of program, I'd probably make it a faceless background application with its own A5 world, globals, stack, heap, and all those other things that make writing programs so much easier. - -- Ray Fischer "Convictions are more dangerous enemies of truth ray@netcom.com than lies." -- Friedrich Nietzsche +++++++++++++++++++++++++++ From: cole@alexia.lis.uiuc.edu (Sandra Stewart-Cole) Date: Mon, 8 Feb 1993 05:24:20 GMT Organization: University of Illinois at Urbana In <1993Feb7.214141.8854@netcom.com> ray@netcom.com (Ray Fischer) writes:< < >>accessible spot turns out not to be that... The situation is that I have an < >>INIT which patches SystemTask in order to get some regular time, and it talks < >>to an external device via the serial port to determine whether to allow the < >>user to do anything.< < >I don't know what you're trying to do, but in my opinion you're not< >suffering nearly enough for some of the truly strange things you're< >doing. No, it's probably not reasonable to assume A5 will be valid< < How sweet of you. :P < The point of this whole thing is machine control. Make the user put a card into a box, and don't let the mac look at events until the card reader says OK. Blank the screen even. The client may even be asking for Mac-controlled handcuffs to keep the user from leaving if he tries to cheat the system. (okay, maybe not THAT bad) And actually, I tracked the beast for a while and found that indeed A5 was valid consistently. It was a different valid set of QD globals involved, but it always was a valid A5. Turns out that wasn't the problem.< < >everytime you intercept SystemTask. Were I writing this sort of< >program, I'd probably make it a faceless background application with< >its own A5 world, globals, stack, heap, and all those other things< >that make writing programs so much easier.< < But that makes it impossible to make secure. Try a cmd-opt-esc on any application, no matter how invisible it is. Also, since this evil little fascist INIT is aimed at making people pay for time used on a Mac, it also controls printing, so has to patch PrGlue. You can't do global trap patches from anywhere but an INIT. (also, since this is a INIT that loads into the system heap, detaches, and locks itself in for the duration, it has a perfectly good heap without any of the management problems. As long as it has someones A5 to leech off of for QD globals, the rest of the internal globals are just managed thru A4 and are a non-issue. It's impossible to ever run on a mac without a stack)< < The solution to this mess was not in going to some sort of other form of code, but in taking a closer look at what *I* was doing. Seems that in the course of leeching time from the system in places other than SystemTask and using them to call SystemTask when my main patch was getting bored (like amidst 50k-line compiles or launching Word) I failed to totally deal with a little re-entrancy problem that was resulting in the potential for drivers (or DA's, whcih are just public-access drivers, sorta like cabbies.) to effectively be re-entered once if they happened to make certain calls during initialization. I got no infinite recursions, but I did get that really wigged behavior and crashes in certain DA's. The fix was to give up on helping out the OS by cvalling SystemTask when no app had recently, and instead just do what *I* needed to do to keep my little outside controller happy (it insists on a ping-pong every minute, and gives me less than 10 seconds to respond before it errors out, leaving my software no choice but to kill the user... figurative at this alpha stage, but the client is interested in making that part literal I think) Bill Stewart-Cole --------------------------- From: joshr@kronos.arc.nasa.gov (Joshua Rabinowitz-Summer-91) Subject: appleevents Date: 8 Jan 93 22:08:23 GMT Organization: NASA/ARC Information Sciences Division Hey all: I`ve been working for quite some time now on a program that runs concurrently and closely with hypercard. I would like to send misc/dosc events from hypercard to my app. (and vice/versa) I have it working from my app to hypercard, but the hypercard error messages are not passed back correctly. The notiication manager blinks the multifinder icon in top right with the HC icon, but I don't think tthere is any other sign that there was an error. The user must switch to HC before recieving the error message. What I would like is 1) when my app sends an AE to hypercard, it waits for HC to finish, and READS `the result' out of the returned ae. Currently it sends it and waits for HC to finish, but does not unload "the result" from the reply. In addition, HC does not appear to work any faster in the background while processing the AE than any other time. Cant the client somehow give up almost all CPU time while waiting for the AE to finish? 2) To be able to send dosc events to my program. I think I know how to send it (using the SendAppleEvent XCMD stack), but I am unclear on the TCL half of the receiving. I know that when it comes into the event loop, it will be packaged by TCL into a CAppleEvent. But I am unclear what to do next. Has anyone written, or know of, a dosc handler code for tcl (or straight C?) I would be happy to share my existing code. If anyone is familiar with these issues, and could help me troublewhoot this, pls. give me a hand. joshr@kronos.arc.nasa.gov PS - email is better for me than News. Following find Think C code for my "Send Hypercard Script" function If someone can see me making some mistakes, I'd be real thankful for the tips. /****************************************************/ #include "SendToHyp.h" #include #include "Constants.h" #include extern CursHandle gWatchCursor;` /* Watch cursor for waiting */ Boolean SendToHypercard(char *messageToSend) { // mostly from Programming for SYS7, p. 145 // pseudocode: // GetProcessInformation() // create address descriptor from above info // create apple event with AECreateAppleEvent() and // pass it address descriptor // use AEManager to add descriptors with AEPutParamPtr or AEPutParamDesc // call AESend // check for errors // dispose of copies of descriptor records // process the AEReply AEAddressDesc theAddressDesc; AEDesc theResultDescriptor; AppleEvent theAE, theReply; OSErr myError, sendError; TargetID myTarget; PortInfoRec myPortInfo; DescType actualType, theDescriptorType; long eventError, actualSize, theResultSize; ProcessSerialNumber process; Boolean fSentSuccess = FALSE; if (FindHypercardProcessNumber(&process) == FALSE) return FALSE; // create descriptor of serial number myError = AECreateDesc(typeProcessSerialNumber, (Ptr)&process, sizeof(process), &theAddressDesc); FailOSErr(myError); // create the apple event myError = AECreateAppleEvent(kHypercardMessageEventClass, kHypercardMessageEventID, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &theAE); FailOSErr(myError); // dispose of descriptor, (which is now copied into the AE ?) myError = AEDisposeDesc( &theAddressDesc); /* we don't need it anymore */ FailOSErr(myError); // put the string in a a ParamPtr myError = AEPutParamPtr(&theAE, keyDirectObject, typeChar, messageToSend, strlen(messageToSend) ); FailOSErr(myError); SetCursor(*gWatchCursor); /*** SHOW WATCH CURSOR ***/ //printf("sending\n"); /// ** DEBUGGING // Send it sendError = AESend(&theAE, &theReply, kAEWaitReply + kAECanInteract, kAEHighPriority, kNoTimeOut, myIdleProc, 0L); if (sendError) { myError = AEDisposeDesc(&theAE); FailOSErr(sendError); FailOSErr(myError); } //printf("no send error\n"); /// ** DEBUGGING myError = AEDisposeDesc(&theAE); FailOSErr(myError); //printf("AEDisposeDesc(&theAE) worked \n"); /// ** DEBUGGING /*** WORKS TO HERE ****/ /** GET RESULT FROM HYPERCARD ***/ myError = AEGetParamPtr( &theReply, keyErrorNumber, typeChar, &actualType, (Ptr)(&eventError), sizeof(eventError), &actualSize); if (myError != errAEDescNotFound) { // a descriptor was found if (myError) { myError = AEDisposeDesc( &theReply); // SysBeep(1); FailOSErr(myError); } else { if (eventError != noErr) { myError=AEDisposeDesc( &theReply); // SysBeep(1); } } } myError = AEGetParamDesc(&theReply, keyDirectObject, typeChar, &theResultDescriptor); if (myError) { /* no direct object exists ! */ // there is no reply ? myError = AEDisposeDesc( &theReply); FailOSErr(myError); } else { // there is a reply ! myError = AESizeOfParam( &theReply, keyDirectObject, &theDescriptorType, &theResultSize); FailOSErr(myError); } /***** PUT IT INTO SCRAP -- CRASHES MACHINE if run //myError = ZeroScrap(); // FailOSErr(myError); //myError = PutScrap( theResultSize, 'TEXT', // *theResultDescriptor.dataHandle); //FailOSErr(myError); *****/ /**** appears never loaded ***/ //myError = AEDisposeDesc(&theResultDescriptor); //FailOSErr(myError); myError = AEDisposeDesc(&theReply); FailOSErr(myError); fSentSuccess = TRUE; SetCursor(&arrow); /* Use arrow cursor again */ return fSentSuccess; } - -- - ---------------------------------- #include Josh Rabinowitz, Mac TCL programmer joshr@kronos.arc.nasa.gov "Me lost my cookie at the disco." -- Cookie Monster - -- - ---------------------------------- #include Josh Rabinowitz, Mac TCL programmer joshr@kronos.arc.nasa.gov "Me lost my cookie at the disco." -- Cookie Monster +++++++++++++++++++++++++++ From: rson@rhi.hi.is (Mimir Reynisson) Date: 5 Feb 93 10:29:45 GMT Well here we go again, Oki I have support for the four basic AppleEvents (not really hard) since there's lots of examples on how to do that. However, now I hear something about being recordable, which apparently means sending AppleEvents to myself for each user event. Now sending and receiving AppleEvents is not so hard, but what confuses me is do those "user events" have to be of a certain class? or type? or what ever? and do they have to take some special parameters? or do I simply define those AE for myself, with my own class and type and paramteres? P.S.: I believe that some of the AE docs were in fact written for green bugeyed aliens, but that's just me I guess. +++++++++++++++++++++++++++ From: leonardr@netcom.com (Leonard Rosenthol) Date: 5 Feb 93 20:32:03 GMT Organization: Netcom Online Communications Services (408-241-9760 login: guest) In article <6144@krafla.rhi.hi.is> rson@rhi.hi.is (Mimir Reynisson) writes: >Well here we go again, > > Oki I have support for the four basic AppleEvents (not really hard) >since there's lots of examples on how to do that. > Well that's a start ;) >However, now I hear >something about being recordable, which apparently means sending >AppleEvents to myself for each user event. > Yes and no. Recordability is only useful if you support "real" Apple events (ie. something useful beyond the required suite), so that users can use recording to have scripts (ie. AppleScript) written for them (like a "Watch me" mode in a communications program). >P.S.: I believe that some of the AE docs were in fact written for >green bugeyed aliens, but that's just me I guess. > They were - have you ever met Jon Pugh ;) - -- - ----------------------------------------------------------------------------- Leonard Rosenthol Internet: leonardr@netcom.com Director of Advanced Technology AppleLink: MACgician Aladdin Systems, Inc. GEnie: MACgician +++++++++++++++++++++++++++ From: draper@odin.mda.uth.tmc.edu (E.J. Draper) Date: 5 Feb 1993 22:28:28 GMT Organization: U.T.M.D. Anderson Cancer Center In article <1993Feb5.203203.6752@netcom.com> Leonard Rosenthol, leonardr@netcom.com writes: >>P.S.: I believe that some of the AE docs were in fact written for >>green bugeyed aliens, but that's just me I guess. I whined about this very topic a few months back in c.s.m.h. I thought it was important to let Apple know that there are MANY developers, including myself, that are utterly befuddled by the object model. It seems to me that the documentation should be a heck of a lot less esoteric and pedantic and a whole lot more useful to somebody trying to make their application scripting savvy. Has anybody taken the Developer's University course? Is it worth the time and cash? |E|J- ED DRAPER rEpar|D|<- Radiologic/Pathologic Institute The University of Texas M.D. Anderson Cancer Center draper@odin.mda.uth.tmc.edu +++++++++++++++++++++++++++ From: leonardr@netcom.com (Leonard Rosenthol) Date: 6 Feb 93 05:46:05 GMT Organization: Netcom Online Communications Services (408-241-9760 login: guest) In article <8676@lib.tmc.edu> draper@odin.mda.uth.tmc.edu (E.J. Draper) writes: >Has anybody taken the Developer's University course? Is it worth the >time and cash? > YES!!!!!! The DU class is probably the BEST way to learn the Object Model and Apple events - it's worth every cent!! - -- - ----------------------------------------------------------------------------- Leonard Rosenthol Internet: leonardr@netcom.com Director of Advanced Technology AppleLink: MACgician Aladdin Systems, Inc. GEnie: MACgician +++++++++++++++++++++++++++ From: Jim.Matthews@dartmouth.edu (Jim Matthews) Date: 8 Feb 93 14:33:14 GMT Organization: Dartmouth College, Hanover, NH E.J. Draper writes > Has anybody taken the Developer's University course? Is it worth the > time and cash? I "took" the DU self-study course (i.e. the one that APDA sells) and it was well worth the time and money. Between that and reading the article in develop issue #10 four or five times I finally feel like I know what's going on. The DU course is especially nice because there are exercises and you implement an AE object; it makes all the concepts and abstractions real. It's also very valuable to fool around with Toy Surprise (assuming you can get ahold of the AppleScript Beta CD). You can have your accessors and tokens and handlers and terminology all working but you may not see flaws in your basic object design until you try to write scripts for your app. That experience helps clarify the basic design decisions: whether to make something a property or an element, a new class or an extension of an existing one, and whether to use a new event or a re-interpretation of a core event. There are some things that I still don't understand, and that aren't covered in the documentation (such as, what's a reasonable way to implement inheritence?), but it's hard enough to get started already. Jim Matthews Dartmouth Software Development --------------------------- From: mark@pokey.jsc.nasa.gov (Mark Manning) Subject: Help with strings.... Organization: NASA Date: Fri, 5 Feb 1993 16:24:11 GMT I have to admit I liked the sprintf thing better than the short shameful routine I wrote. Good Thinking! sprintf( newbuf, "This is the number #%d", shortnum ); Now why didn't >I< think of that! ;) +++++++++++++++++++++++++++ From: heksterb@cs.utwente.nl (Ben Hekster) Organization: University of Twente, Dept. of Computer Science Date: Tue, 9 Feb 1993 16:37:37 GMT Ok, since everyone else seems to be posting their favorite string munging routines, here's mine. I wrote it in C++ but a quick look would suggest that it's almost ANSI C. It works along the lines of the Dialog Manager's ParamText function, except that there is no bound on the number of arguments that may be substituted. Caveat: the price for this flexibility is a slight dependency on the order in which your compiler passes arguments in variable-length argument lists. This particular code works under MPW's C++/C. E.g., long delay = 2, model = 300; unsigned char strDelay[16], strModel[16]; NumToString(delay, strDelay); NumToString(model, strModel); unsigned char subsituted[256]; ParamString( result, "\pI've had my Apple CD^0 on order for ^1 months", strModel, strDelay ); constructs the appropriate string in "result". This scheme has the advantage that your string constructions aren't hard-coded and can be localized simply by using a different template string: "\pAinda sa~o ^1 meses que espero por meu CD^0" Enjoy! void ParamString(unsigned char *result, const unsigned char *templat, ...); /* ParamString Build a Pascal string from the given template and argument substitutions An argi may be NULL */ #pragma segment Main void ParamString( unsigned char *const result, const unsigned char *const templat, ... // const unsigned char *argi ) { const unsigned char **arg = &templat + 1; // *** implementation-dependent register unsigned char *r = result; register const unsigned char *t = templat; // keep copying characters from the template into the result unsigned char rlength = *r++ = 0; unsigned char tlength = *t++; while (tlength > 0 && rlength < 255) // ordinary character? if (*t != '^') { *r++ = *t++; rlength++; tlength--; } // argument substitution? else { t++; tlength--; // which argument? tlength--; const unsigned char *a = arg[*t++ - '0']; // copy the argument into the result if (a) for (unsigned char alength = *a++; alength > 0 && rlength < 255; alength--, rlength++) *r++ = *a++; } *result = rlength; } - -- Ben `Hackster' Hekster | "In the comfort of this room heksterb@cs.utwente.nl | the challenge died" --------------------------- From: tnorthtj@cc.curtin.edu.au (Tim North) Subject: Getting a dirID from an FSSpec. HELP! Organization: Curtin University of Technology Date: Mon, 8 Feb 1993 01:37:44 GMT 1. I have an FSSpec for a *folder* that the user has selected using a CustomGetFile dialog. 2. I then wish to search this folder. No problem. The problem is that the FSSpec contains the dirID for the *parent* directory of the selected folder. So when I say... StandardFileReply myReply; myReply = DoGetDirectory(); Search(myReply.sfFile.vRefNum, myReply.sfFile.parID); ...it searches the *parent* of the selected folder, not the selected folder itself. Question: How do I get the dirID of a folder given an FSSpec for it? Many thanks in advance! Tim North. - ------------------------------------------------------------------------------- _--_|\ | Dept Computer Engineering, Curtin University of Technology / \ | Perth. Western Australia. 6102. Phone: (+61 9) 351 7908 - -->\_.--._/ | Internet: North_TJ@cc.curtin.edu.au FAX: (+61 9) 351 2584 v | - ------------------------------------------------------------------------------- +++++++++++++++++++++++++++ From: brunner@crchh447.NoSubdomain.NoDomain (James Brunner) Date: Mon, 8 Feb 1993 16:38:53 GMT Organization: BNR, Inc. In article <1993Feb8.103744.1@cc.curtin.edu.au>, tnorthtj@cc.curtin.edu.au (Tim North) writes: |> 1. I have an FSSpec for a *folder* that the user has selected using a |> CustomGetFile dialog. |> |> 2. I then wish to search this folder. No problem. The problem is that the |> FSSpec contains the dirID for the *parent* directory of the selected |> folder. |> |> Question: How do I get the dirID of a folder given an FSSpec for it? I don't have time to write the whole thing up, but two ideas come to mind. 1) you could try FSMakeFSSpec to make the spec for an file IN the directory you want. Make up a name, FSMakeFSSpec will probably return fnfErr, but the spec is still valid. FSMakeFSSpec will resolve partial paths, so you could do something like (NOT actual code, this is from my head): FSMakeFSSpec(spec.parID, spec.vRefNum, spec.name+":filename", &newspec) 2) Take a good look at PBGetCatInfo. (Thanks Peter Lewis for showing me this one.) PBGetCatInfo is a great routine, much more powerful than it initially looks. It will resolve partial pathnames. - -- - --------------------------------------------------------------------------- Jim Brunner - (brunner@bnr.ca) All opinions are my own and have nothing whatsoever to do with BNR, NT, NTI, Bell Canada, or any of the BCE corporations or affiliates. +++++++++++++++++++++++++++ From: neeri@iis.ethz.ch (Matthias Neeracher) Date: 8 Feb 93 23:04:40 GMT Organization: Integrated Systems Laboratory, ETH, Zurich In article , brunner@crchh447.NoSubdomain.NoDomain (James Brunner) writes: > In article <1993Feb8.103744.1@cc.curtin.edu.au>, tnorthtj@cc.curtin.edu.au (Tim North) writes: > |> 1. I have an FSSpec for a *folder* that the user has selected using a > |> CustomGetFile dialog. > |> > |> 2. I then wish to search this folder. No problem. The problem is that the > |> FSSpec contains the dirID for the *parent* directory of the selected > |> folder. > |> > |> Question: How do I get the dirID of a folder given an FSSpec for it? > I don't have time to write the whole thing up, but two ideas come to mind. > 1) you could try FSMakeFSSpec to make the spec for an file IN the directory > you want. Make up a name, FSMakeFSSpec will probably return fnfErr, but the > spec is still valid. FSMakeFSSpec will resolve partial paths, so you could > do something like (NOT actual code, this is from my head): > FSMakeFSSpec(spec.parID, spec.vRefNum, spec.name+":filename", &newspec) > 2) Take a good look at PBGetCatInfo. (Thanks Peter Lewis for showing me this > one.) PBGetCatInfo is a great routine, much more powerful than it initially > looks. It will resolve partial pathnames. Something like this might work: CInfoPBRec info; FSSpec fs; /* Filled in by you */ info.dirInfo.ioVRefNum = fs.vRefNum; info.dirInfo.ioDrDirID = fs.parID; info.dirInfo.ioNamePtr = fs.name; info.dirInfo.ioFDirIndex = -1; info.dirInfo.filler2 = 0; PBGetCatInfoSync(&info); /* Imagine an error handler for the above :-) */ fs.parID = cb.dirInfo.ioDrParID; Matthias - ----- Matthias Neeracher neeri@iis.ethz.ch "You must have picked up that copy of Scarlett instead of Inside Mac when you tried to find the right call..." -- Keith Rollin +++++++++++++++++++++++++++ From: peter@cujo.curtin.edu.au (Peter N Lewis) Organization: NCRPDA, Curtin University Date: Tue, 9 Feb 1993 04:05:45 GMT In article <1993Feb8.103744.1@cc.curtin.edu.au>, tnorthtj@cc.curtin.edu.au (Tim North) wrote: > > 1. I have an FSSpec for a *folder* that the user has selected using a > CustomGetFile dialog. > Question: How do I get the dirID of a folder given an FSSpec for it? "Learn to Love PBGetCatInfo" var pb:CInfoPBRec; fs:FSSpec; pb.ioNamePtr:=@fs.name; pb.ioVRefNum:=fs.vRefNum; pb.ioDirID:=fs.parID; pb.ioFDirIndex:=0; oe:=PBGetCatInfo(@pb,false); The dir ID of the folder is now in ioDrDirID, the par ID of the folder should be in ioDrParID. PBGetCatInfo is one of the most useful File Manager calls. Its very simple to use, it takes only those four parameters above, and will index thru directories, resolve partial paths, get directory names or ID, etc. Have fun, Peter. _______________________________________________________________________ Peter N Lewis Ph: +61 9 368 2055 +++++++++++++++++++++++++++ From: neeri@iis.ethz.ch (Matthias Neeracher) Organization: Swiss Federal Institute of Technology (ETH), Zurich, CH Date: Tue, 9 Feb 1993 13:31:42 GMT I stupidly wrote: >In article , brunner@crchh447.NoSubdomain.NoDomain (James Brunner) writes: >> In article <1993Feb8.103744.1@cc.curtin.edu.au>, tnorthtj@cc.curtin.edu.au (Tim North) writes: >> |> 1. I have an FSSpec for a *folder* that the user has selected using a >> |> CustomGetFile dialog. >> |> >> |> 2. I then wish to search this folder. No problem. The problem is that the >> |> FSSpec contains the dirID for the *parent* directory of the selected >> |> folder. >> |> >> |> Question: How do I get the dirID of a folder given an FSSpec for it? >> I don't have time to write the whole thing up, but two ideas come to mind. >> 1) you could try FSMakeFSSpec to make the spec for an file IN the directory >> you want. Make up a name, FSMakeFSSpec will probably return fnfErr, but the >> spec is still valid. FSMakeFSSpec will resolve partial paths, so you could >> do something like (NOT actual code, this is from my head): >> FSMakeFSSpec(spec.parID, spec.vRefNum, spec.name+":filename", &newspec) >> 2) Take a good look at PBGetCatInfo. (Thanks Peter Lewis for showing me this >> one.) PBGetCatInfo is a great routine, much more powerful than it initially >> looks. It will resolve partial pathnames. >Something like this might work: >CInfoPBRec info; >FSSpec fs; /* Filled in by you */ >info.dirInfo.ioVRefNum = fs.vRefNum; >info.dirInfo.ioDrDirID = fs.parID; >info.dirInfo.ioNamePtr = fs.name; >info.dirInfo.ioFDirIndex = -1; Aaaaaarrrgggg !!! Stop the presses. The correct value is 0, not -1 >info.dirInfo.filler2 = 0; >PBGetCatInfoSync(&info); >/* Imagine an error handler for the above :-) */ >fs.parID = cb.dirInfo.ioDrParID; --------------------------- End of C.S.M.P. Digest **********************